@tool
class_name PathBuilder
extends ExPathBuilder

@export_group("Reference")
@export var volume : BoxFrame
@export var path_voxel : BoxFrame
@export var connections : BoxFrame
@export var path_line : BoxFrame
@export var valid_referece : Node3D
@export var test_shape_3D : CollisionShape3D

@export_group("Visualization")
@export_range( 1.0, 10.0 ) var width : float = 1.0

@export_group("Volume")
@export var min_voxel_size: int
@export var volume_size : Vector3 = Vector3(1.0, 1.0, 1.0):
	set(val):
		volume_size = val
		update_reference()

@export_group("Build Path")
@export var start : Node3D
@export var end : Node3D

enum E_FileOperation {
	E_FILE_EXPORT,
	E_FILE_IMPORT,
}
var file_operation: E_FileOperation

func _ready():
	Init( get_world_3d().direct_space_state )
	volume.color = Color.ORANGE
	path_voxel.color = Color.BLUE
	connections.color = Color.WHITE
	path_line.color = Color.GREEN
	update_reference()

	path_voxel.clear_surfaces()
	connections.clear_surfaces()
	path_line.clear_surfaces()
	pass

func update_reference():
	if Engine.is_editor_hint() && volume != null:
		volume.draw_a_box( Vector3.ZERO, volume_size / 2.0, width)
	pass

func build_road_map():
	BuildSpaceInfo( volume_size, min_voxel_size, valid_referece.global_position )
	draw_gizmo_space_info()
	pass

func build_path():
	print("Build Path")
	print("Start pt: ", start.global_position )
	print("End pt: ", end.global_position )
	
	var path: Array = Array()
	FindPath( start.global_position, end.global_position, 1.5, path )
	print("path points num: ", path.size() )
	path_line.clear_surfaces()
	if path.size() > 0 :
		path_line.draw_line_list( path, BoxFrame.LINE_MODE.LM_WAYPOINTS, width )
	pass

func draw_gizmo_space_info():
	var centers: Array = Array()
	var sizes: Array = Array()
	var lines: Array = Array()
	
	FillPathAreas( centers, sizes )
	FillConnectionsLines( lines )
	print("area cnt: ", centers.size() )
	print("line pt cnt: ", lines.size() )
	
	path_voxel.clear_surfaces()
	connections.clear_surfaces()
	if centers.size() > 0 : 
		path_voxel.draw_box_list( centers, sizes, width )
		connections.draw_line_list( lines, BoxFrame.LINE_MODE.LM_ENDPOINTS, width )
	pass

func export_space_info():
	file_operation = E_FileOperation.E_FILE_EXPORT
	open_file_dialog()
	pass

func import_space_info():
	file_operation = E_FileOperation.E_FILE_IMPORT
	open_file_dialog()
	pass

func test_detector_res():
	var space_state = get_world_3d().direct_space_state
	var query = PhysicsShapeQueryParameters3D.new()
	query.collision_mask = 1 << 0
	query.transform = test_shape_3D.transform
	query.shape = test_shape_3D.shape
	var colCnt = space_state.intersect_shape( query ).size()
	print("Test Collision Cnt: ", colCnt );
	pass

func open_file_dialog():
	var base_control = EditorInterface.get_base_control()
	var dialog = FileDialog.new()
	base_control.add_child(dialog)
	dialog.mode = FileDialog.MODE_WINDOWED
	if file_operation == E_FileOperation.E_FILE_EXPORT:
		dialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE
	elif file_operation == E_FileOperation.E_FILE_IMPORT:
		dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
	dialog.access = FileDialog.ACCESS_FILESYSTEM
	dialog.set_size( Vector2i(800, 600) )
	dialog.popup_centered()
	dialog.file_selected.connect( _on_file_dialog_file_selected )
	pass

func _on_file_dialog_file_selected( path: String ):
	match file_operation:
		E_FileOperation.E_FILE_EXPORT:
			ExportSpaceInfo( path )
			pass
		E_FileOperation.E_FILE_IMPORT:
			var dic : Dictionary = Dictionary()
			ImportSpaceInfo( path )
			FetchVolumeInfo( dic )
			min_voxel_size = dic["min_size"]
			volume_size = dic["volume"]
			valid_referece.global_position = dic["center"]
			draw_gizmo_space_info()
			pass
	pass
